package com.lcj.bff.driver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.lcj.bff.driver.controller.form.*;
import com.lcj.bff.driver.feign.*;
import com.lcj.bff.driver.service.OrderService;
import com.lcj.common.entity.OrderStatusEnum;
import com.lcj.common.exception.AochException;
import com.lcj.common.util.PageUtils;
import com.lcj.common.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.HashMap;

@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderServiceApi orderServiceApi;

    @Resource
    private CstServiceApi cstServiceApi;

    @Resource
    private NebulaServiceApi nebulaServiceApi;

    @Resource
    private RuleServiceApi ruleServiceApi;

    @Resource
    private SnmServiceApi snmServiceApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    @LcnTransaction
    @Transactional
    public String acceptNewOrder(AcceptNewOrderForm form) {
        Result r = orderServiceApi.acceptNewOrder(form);
        String result = MapUtil.getStr(r, "result");
        return result;
    }

    @Override
    public HashMap searchDriverExecuteOrder(AcceptNewOrderForm form) {
        //查询订单信息
        Result r = orderServiceApi.searchDriverExecuteOrder(form);
        HashMap orderMap = (HashMap) r.get("result");

        //查询客户信息
        long customerId = MapUtil.getLong(orderMap, "customerId");
        CustomerIdForm customerIdForm = new CustomerIdForm();
        customerIdForm.setCustomerId(customerId);
        r = cstServiceApi.searchCustomerInfoInOrder(customerIdForm);
        HashMap cstMap = (HashMap) r.get("result");

        HashMap map = new HashMap();
        map.putAll(orderMap);
        map.putAll(cstMap);
        return map;
    }

    @Override
    public HashMap searchDriverCurrentOrder(DriverIdForm form) {
        Result r = orderServiceApi.searchDriverCurrentOrder(form);
        HashMap orderMap = (HashMap) r.get("result");

        if (MapUtil.isNotEmpty(orderMap)) {
            HashMap map = new HashMap();
            //查询代驾客户信息
            long customerId = MapUtil.getLong(orderMap, "customerId");
            CustomerIdForm customerIdForm = new CustomerIdForm();
            customerIdForm.setCustomerId(customerId);
            r = cstServiceApi.searchCustomerInfoInOrder(customerIdForm);
            HashMap cstMap = (HashMap) r.get("result");
            map.putAll(orderMap);
            cstMap.remove("id");
            map.putAll(cstMap);
            return map;
        } else {
            return null;
        }
    }

    @Override
    public HashMap searchOrderForMoveById(SearchOrderForm form) {
        Result r = orderServiceApi.searchOrderForMoveById(form);
        HashMap map = (HashMap) r.get("result");
        return map;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int arriveStartPlace(ArriveStartPlaceForm form) {
        Result r = orderServiceApi.arriveStartPlace(form);
        int rows = MapUtil.getInt(r, "rows");
        if (rows == 1) {
            //发送通知消息
            SendPrivateMessageForm messageForm = new SendPrivateMessageForm();
            messageForm.setReceiverIdentity("customer");
            messageForm.setReceiverId(form.getCustomerId());
            messageForm.setTtl(24 * 3600 * 1000);
            messageForm.setSenderId(0L);
            messageForm.setSenderIdentity("system");
            messageForm.setSenderName("随行打车");
            messageForm.setMsg("司机已到达接送点，请及时上车");
            snmServiceApi.sendPrivateMessageSync(messageForm);
        }
        return rows;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int startDriving(StartDrivingForm form) {
        SearchOrderForm orderForm = new SearchOrderForm();
        orderForm.setOrderId(form.getOrderId());
        int rows = 0;
        try{
            Result r = orderServiceApi.startDriving(form);
            rows = MapUtil.getInt(r, "rows");
            if(rows==1){
                nebulaServiceApi.insertOrderMonitoring(orderForm);
                //发送通知消息
                SendPrivateMessageForm messageForm = new SendPrivateMessageForm();
                messageForm.setReceiverIdentity("customer");
                messageForm.setReceiverId(form.getCustomerId());
                messageForm.setTtl(3 * 24 * 3600 * 1000);
                messageForm.setSenderId(0L);
                messageForm.setSenderIdentity("system");
                messageForm.setSenderName("随行打车");
                messageForm.setMsg("司机已开始行程");
                snmServiceApi.sendPrivateMessageSync(messageForm);
            }
        } catch (Exception e) {
            //还原被删除的确认司机到达Redis缓存
            redisTemplate.opsForValue().set("order_driver_arrived#" + orderForm.getOrderId(), "2");
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return rows;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int updateOrderStatus(UpdateOrderStatusForm form) {
        Result r = orderServiceApi.updateOrderStatus(form);
        int rows = MapUtil.getInt(r, "rows");
        //判断订单的状态，然后实现后续业务
        if(rows != 1) {
            throw new AochException("订单状态修改失败!");
        }
        //未支付状态则发送支付消息给乘客
        if(form.getStatus() == OrderStatusEnum.UNPAID.getCode().intValue()) {
            SendPrivateMessageForm messageForm = new SendPrivateMessageForm();
            messageForm.setReceiverIdentity("customer_bill");
            messageForm.setReceiverId(form.getCustomerId());
            //messageForm.setTtl(3 * 24 * 3600 * 1000);
            messageForm.setSenderId(0L);
            messageForm.setSenderIdentity("system");
            messageForm.setSenderName("随行打车");
            messageForm.setMsg("您有行程订单待支付");
            snmServiceApi.sendPrivateMessageSync(messageForm);
        }
        return rows;
    }

    /**
     * 计算订单费用
     * @param form
     * @return
     */
    @Override
    @Transactional
    @LcnTransaction
    public int updateOrderBill(UpdateBillFeeForm form) {
        /*
         * 1.判断司机是否关联该订单
         */
        SearchOrderForm searchOrderForm = new SearchOrderForm();
        searchOrderForm.setOrderId(form.getOrderId());
        searchOrderForm.setDriverId(form.getDriverId());
        Result r = orderServiceApi.validDriverOwnOrder(searchOrderForm);
        JSONObject orderInfo = JSONObject.parseObject(JSON.toJSONString(r.get("result")));
        boolean bool = orderInfo.getBooleanValue("valid");
        if (!bool) {
            throw new AochException("司机未关联该订单,无权限操作该订单");
        }
        /*
         * 2.查询订单数据
         */
        JSONObject orderInfoDetail = orderInfo.getJSONObject("orderInfo");
        String acceptTime = orderInfoDetail.getString("acceptTime");
        String startTime = orderInfoDetail.getString("startTime");
        int waitingMinute = orderInfoDetail.getIntValue("waitingMinute");
        String favourFee = orderInfoDetail.getString("favourFee");

        /*
         * 3.计算订单里程数据
         */
        r = nebulaServiceApi.calculateOrderMileage(searchOrderForm);
        String mileage= NumberUtil.div((String) r.get("result"),"1000",1, RoundingMode.CEILING).toString();

        /*
         * 4.计算代驾费
         */
        CalculateOrderChargeForm calculateOrderChargeForm = new CalculateOrderChargeForm();
        calculateOrderChargeForm.setMileage(mileage);
        calculateOrderChargeForm.setTime(startTime.split(" ")[1]);
        calculateOrderChargeForm.setMinute(waitingMinute);
        r = ruleServiceApi.calculateOrderCharge(calculateOrderChargeForm);
        HashMap map = (HashMap) r.get("result");
        String mileageFee = MapUtil.getStr(map, "mileageFee");
        String returnFee = MapUtil.getStr(map, "returnFee");
        String waitingFee = MapUtil.getStr(map, "waitingFee");
        //amount = mileageFee + waitingFee + returnFee
        String amount = MapUtil.getStr(map, "amount");
        String returnMileage = MapUtil.getStr(map, "returnMileage");

        /*
         * 5.计算系统奖励费用
         */
        CalculateIncentiveFeeForm form_5 = new CalculateIncentiveFeeForm();
        form_5.setDriverId(form.getDriverId());
        form_5.setAcceptTime(acceptTime);
        r = ruleServiceApi.calculateIncentiveFee(form_5);
        String incentiveFee = (String) r.get("result");

        form.setMileageFee(mileageFee);
        form.setReturnFee(returnFee);
        form.setWaitingFee(waitingFee);
        form.setIncentiveFee(incentiveFee);
        form.setRealMileage(mileage);
        form.setReturnMileage(returnMileage);
        //计算总费用 = amount + toll + parking + other + favour
        String total = NumberUtil.add(amount, form.getTollFee(), form.getParkingFee(), form.getOtherFee(), favourFee).toString();
        form.setTotal(total);

        /*
         * 6.计算分账数据
         */
        CalculateProfitsharingForm form_6 = new CalculateProfitsharingForm();
        form_6.setOrderId(form.getOrderId());
        form_6.setAmount(total);
        r = ruleServiceApi.calculateProfitsharing(form_6);
        map = (HashMap) r.get("result");
        long ruleId = MapUtil.getLong(map, "ruleId");
        String systemIncome = MapUtil.getStr(map, "systemIncome");
        String driverIncome = MapUtil.getStr(map, "driverIncome");
        String paymentRate = MapUtil.getStr(map, "paymentRate");
        String paymentFee = MapUtil.getStr(map, "paymentFee");
        String taxRate = MapUtil.getStr(map, "taxRate");
        String taxFee = MapUtil.getStr(map, "taxFee");
        form.setRuleId(ruleId);
        form.setPaymentRate(paymentRate);
        form.setPaymentFee(paymentFee);
        form.setTaxRate(taxRate);
        form.setTaxFee(taxFee);
        form.setSystemIncome(systemIncome);
        form.setDriverIncome(driverIncome);

        /*
         * 7.更新代驾费账单数据
         */
        r = orderServiceApi.updateBillFee(form);
        int rows = MapUtil.getInt(r, "rows");
        return rows;
    }

    @Override
    public HashMap searchReviewDriverOrderBill(SearchOrderForm form) {
        Result r = orderServiceApi.searchReviewDriverOrderBill(form);
        HashMap map = (HashMap) r.get("result");
        return map;
    }

    @Override
    public Integer searchOrderStatus(SearchOrderForm form) {
        Result r = orderServiceApi.searchOrderStatus(form);
        Integer status = (Integer) r.get("result");
        return status;
    }

    @Override
    @Transactional
    @LcnTransaction
    public String updateOrderAboutPayment(long driverId, SearchOrderForm form) {
        form.setDriverId(driverId);
        Result r = orderServiceApi.validDriverOwnOrder(form);
        boolean bool = MapUtil.getBool(r, "result");
        if (!bool) {
            throw new AochException("司机未关联该订单");
        }

        r = orderServiceApi.updateOrderAboutPayment(form);
        String result = MapUtil.getStr(r, "result");
        return result;
    }

    @Override
    public PageUtils searchDriverOrderByPage(SearchDriverOrderByPageForm form) {
        Result r = orderServiceApi.searchDriverOrderByPage(form);
        HashMap map = (HashMap) r.get("result");
        PageUtils pageUtils = BeanUtil.toBean(map, PageUtils.class);
        return pageUtils;
    }

    @Override
    public HashMap searchOrderById(SearchOrderForm form) {
        //查询订单信息
        Result r = orderServiceApi.searchOrderById(form);
        HashMap orderMap = (HashMap) r.get("result");

        //查询客户信息
        long customerId = MapUtil.getLong(orderMap, "customerId");
        CustomerIdForm form_1 = new CustomerIdForm();
        form_1.setCustomerId(customerId);
        r = cstServiceApi.searchCustomerInfoInOrder(form_1);
        HashMap cstMap = (HashMap) r.get("result");

        //查询评价信息
        int status = MapUtil.getInt(orderMap, "status");
        HashMap cmtMap = new HashMap();
        if (status >= OrderStatusEnum.PAID.getCode().intValue()) {
            SearchOrderForm form_2 = new SearchOrderForm();
            form_2.setOrderId(form.getOrderId());
            form_2.setDriverId(form.getDriverId());
            r = orderServiceApi.searchCommentByOrderId(form_2);
            if (r.containsKey("result")) {
                cmtMap = (HashMap) r.get("result");
            } else {
                //未评价默认好评
                cmtMap.put("rate", 5);
            }
            //已完成订单屏蔽客户电话
            String tel = MapUtil.getStr(cstMap,"tel");
            cstMap.replace("tel", tel.substring(0,3) + "*****" + tel.substring(8));
        }

        HashMap map = new HashMap();
        map.putAll(orderMap);
        map.putAll(cstMap);
        map.put("comment",cmtMap);
        return map;
    }
}